#ifndef VENUS_HARDWARE_SHADOW_MAP_HW_SHADOWMAP_DEMO_H
#define VENUS_HARDWARE_SHADOW_MAP_HW_SHADOWMAP_DEMO_H

#include "common/venus.h"
#include <map>
#include "ui/glut_window.h"
#include "graphics/camera.h"
#include "graphics/fps_counter.h"

namespace venus {
#define TEX_WIDTH 1024
#define TEX_HEIGHT 1024
struct Light {
  Light() : pos(0, 2, 2), at(0, 0, 0), fovy(60.f), z_near(.5f), z_far(5.f),
            width(TEX_WIDTH), height(TEX_HEIGHT) { }
  Point pos;
  Point at;
  float fovy, z_near, z_far;
  int width, height;
};
struct tweak
{
  string name;
  float val;
  float incr;
};
class HwShadowMapDemo : public GlutWindow {
public:
  HwShadowMapDemo() 
      : GlutWindow("Hardware ShadowMap Demo",10, 10, 800, 600, 
                   GLUT_RGBA|GLUT_DOUBLE),
        fps_counter_(FpsCounter::kOverTime, 0.3) {
    fbo_ = NULL;
    decal_tex_ = NULL;
    light_tex_ = NULL;
    shadow_map_ = NULL;
  }
  ~HwShadowMapDemo();
  bool Initialize();
  void OnIdle();
  void OnDisplay();
  void OnResize(int width, int height);
  void OnKeyboard(unsigned char key, int x, int y);
private:
  bool CreateObjects();
  void LargestSquarePowerOfTwoViewport();
  void RenderSceneFromLightView();
  void RenderSceneFromeCameraView();
  void RenderSceneFromeCameraViewWithShadow();
  void RenderScene(glh::glut_simple_mouse_interactor &view);
  void UpdateShadowMap();
private:
  Light light_;
  glh::glut_perspective_reshaper reshaper, lightshaper;
  glh::glut_simple_mouse_interactor camera, object, spotlight;
  glh::glut_simple_mouse_interactor *current_interactor;
  std::map<string, tweak> tweaks;
  std::map<string, tweak>::iterator curr_tweak;
  FpsCounter fps_counter_;
  ImageTextureGL *decal_tex_;
  ImageTextureGL *light_tex_;
  ImageTextureGL *shadow_map_;
  GLuint quad_, wire_cube_, teapot_;
  FramebufferObject *fbo_;
  int render_method_;
  static const int shadow_map_width_ = TEX_WIDTH;
  static const int shadow_map_height_ = TEX_WIDTH;
};
} // namespace venus

#endif // VENUS_HARDWARE_SHADOW_MAP_HW_SHADOWMAP_DEMO_H
